package org.vectrics.recruiter.location;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.jsp.JspException;

import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.location.Location;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.Request;
import org.vectrics.struts.VectricsActionData;
import org.vectrics.struts.VectricsStrutsAction;

/** 
 * Struts Action for saving user selected locations for various contexts for the user's current domain.
 * @author Mike Moore
 *
 */
public class SaveLocationContextsAction extends VectricsStrutsAction {

	@Override
	protected String doExecute(VectricsActionData actionData)
			throws JspException {
		Domain domain = ThreadProperties.getDomain();
		this.saveEntriesForContext(actionData.getRequest(), domain, "job.location");
		this.saveEntriesForContext(actionData.getRequest(), domain, "candidate.location");
		this.saveEntriesForContext(actionData.getRequest(), domain, "candidate.prefer.location");
		
		return "success";
	}


	/**
	 * Save entries for context.
	 * @param domain
	 * @param contextCode
	 */
	private void saveEntriesForContext(Request request, Domain domain, String contextCode) {
		//input.setName(contextCode + "_" + location.getId().toString());
		Collection allLocations = CoreServiceLocator.getLocationService().findAllLocations(domain);
		log.info("saveEntriesForContext - all locations count: " + allLocations.size());
		Collection allPreviousSelectedDomainLocations = CoreServiceLocator.getLocationService()
				.findLocationsForContextType(domain, contextCode);
		log.info("saveEntriesForContext - all previous selected locations count: " + allPreviousSelectedDomainLocations.size());
		Collection currentlySelected = findCurrentlySelectedLocations(contextCode, request, allLocations);
		log.info("saveEntriesForContext - currently selected locations count: " + currentlySelected.size());
		
		this.removePreviousNotSelectedNow(domain, contextCode, allPreviousSelectedDomainLocations, currentlySelected); 		
		this.addNewLocations(domain, contextCode, allPreviousSelectedDomainLocations, currentlySelected);
	}	
	
	
	/**
	 * Return select locations by user for 
	 * @param contextCode
	 * @param request
	 * @param allLocations
	 * @return
	 */
	private Collection findCurrentlySelectedLocations(String contextCode, Request request, 
				Collection allLocations) {
		Set currentlySelectedSet = new HashSet();
		Iterator<String> paramIter = request.getParameterNames().iterator();
		while (paramIter.hasNext()) {
			String paramName = paramIter.next();
			String neededPrefix = contextCode + "_";
			if (paramName.startsWith(neededPrefix)) {
				String locationId = paramName.substring(neededPrefix.length());
				log.info("Param location id: " + locationId);
				Location location = findLocation(new Long(locationId), allLocations);
				currentlySelectedSet.add(location);
			}
		}
		return(currentlySelectedSet);
	}

	private Location findLocation(Long locationId, Collection allLocations) {
		Location location = null;
		Iterator iter = allLocations.iterator();
		while ((iter.hasNext()) && (location == null)) {
			Location currentLocation = (Location)iter.next();
			if (currentLocation.getId().equals(locationId)) {
				location = currentLocation;
			}
			
		}
		return(location);
	}
	
	private void removePreviousNotSelectedNow(Domain domain, String contextCode, 
				Collection previousLocations, Collection currentLocations) {
		Iterator iter = previousLocations.iterator();
		while (iter.hasNext()) {
			Location previousLocation = (Location)iter.next();
			if (this.findLocation(previousLocation.getId(), currentLocations) == null) {
				log.info("Could not find previous location as currently selected: " + previousLocation
						+ " - removing.");
				CoreServiceLocator.getLocationService().removeDomainLocation(domain, contextCode, previousLocation);
			} else {
				log.info("No change to location: " + previousLocation);
				
			}
		}
	}

	private void addNewLocations(Domain domain, String contextCode, Collection previousLocations, 
			Collection currentLocations) {
		Iterator iter = currentLocations.iterator();
		while (iter.hasNext()) {
			Location currentLocation = (Location)iter.next();
			if (this.findLocation(currentLocation.getId(), previousLocations) == null) {
				log.info("Could not find current location in previous selected: " + currentLocation
						+ " - adding.");
				CoreServiceLocator.getLocationService().createDomainLocation(domain, contextCode, currentLocation);
			} else {
				log.info("No change to location: " + currentLocation);
			}
		}
		
		
	}

	
}
